Skip to content

Harden attestation CBOR parsing#36

Open
leanthebean wants to merge 1 commit into
base:mainfrom
leanthebean:security/attestation-cbor-duplicates
Open

Harden attestation CBOR parsing#36
leanthebean wants to merge 1 commit into
base:mainfrom
leanthebean:security/attestation-cbor-duplicates

Conversation

@leanthebean

Copy link
Copy Markdown
Contributor

Summary

  • Reject duplicate recognized top-level attestation keys instead of using last-write-wins semantics.
  • Require the COSE payload byte string and the parsed outer payload map to be fully consumed.
  • Preserve forward compatibility for unknown keys: unknown duplicate keys are still skipped because they do not affect returned pointers or validation decisions.

Security issue

NitroValidator._parseAttestation accepted duplicate top-level CBOR map keys with last-write-wins behavior. If a signed attestation payload contained two pcrs entries, the second one replaced the first in the returned Ptrs, allowing parsed PCR values to diverge from the first measurements in the signed document. The same overwrite behavior applied to other security-critical pointers such as certificate and cabundle.

The stock AWS-rooted deployment is protected from external attackers by the COSE P-384 signature check and the hard-pinned AWS Nitro root, and AWS NSM emits canonical attestation CBOR. This patch still removes the parser ambiguity so validation correctness does not depend on signer encoder behavior or a custom ICertManager deployment never signing duplicate-key payloads.

The parser also now rejects signed-but-unparsed trailing bytes: data after the declared entries in a definite-length payload map, data after an indefinite map break marker, and bytes after the COSE payload byte string all revert.

Fix

The parser now tracks a bitmask of recognized top-level keys. Any duplicate recognized field reverts with duplicate attestation key; unknown keys remain skippable for forward compatibility.

After parsing, _parseAttestation requires the map cursor to end exactly at the payload boundary, and it requires the payload byte string itself to end exactly at attestationTbs.length. Indefinite maps consume the break marker before the final boundary check.

Tests

  • forge fmt
  • forge test

Added regression coverage for:

  • duplicate pcrs, certificate, and cabundle;
  • duplicate required and optional scalar fields;
  • repeated unknown keys still being skipped;
  • definite map trailing data;
  • indefinite map data after the break marker;
  • bytes after the COSE payload byte string.

Security finding: CBOR duplicate-key last-write-wins and signed-but-unparsed trailing bytes in src/NitroValidator.sol.

Reject duplicate recognized top-level attestation keys in NitroValidator instead of using last-write-wins semantics for pcrs, certificate, cabundle, and other parsed fields.

Require the COSE payload byte string and outer payload map to be fully consumed so signed trailing bytes cannot be silently ignored. Keep unknown keys skippable for AWS forward compatibility.

Add regression coverage for duplicate parsed fields, unknown duplicate compatibility, and trailing signed bytes.
@leanthebean leanthebean force-pushed the security/attestation-cbor-duplicates branch from 104884b to 9a573e9 Compare June 18, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant